<html><head><title>Page Driven Design</title></head>
<body bgcolor="white" text="black">

<table width="95%">
<tr><td width="70%"><h1>Page Driven Design<hr></h1></td>
     <td align="right"><a href="script.html">BACK</a> |
                       <a href="index.html">UP</a> |
                       <a href="summary.html">NEXT</a></td></tr>
<tr><td>

<h2>Two Models for Site Development</h2>

If you used to be a CGI programmer then you likely thing about 
site design like this:
<ol>
  <li>Generate some content (processing step)
  <li>Make it look pretty (page generation step)
</ol>
WebMacro was certainly constructed with you in mind: use the 
Context.put() method to drop data into a context, pick a 
template, and away you go.
<p>
This development process tends to put the programmer in the 
drivers seat: you created some really interesting content, and 
now you want someone to make it look pretty. The template writer
is probably asked to render your data with a nice template.
<p>
However, many websites work the other way around: the template 
writer creates a page, then comes down to engineering and asks
for it to be implemented. 
<p>
WebMacro has extremely strong support for this second model 
of development, called <b>page driven design</b>, which 
empowers the page designer, putting the HTML folk in the 
drivers seat. 
<p>
<h2>Step #1: Write the template first</h2>

With a page driven development process the first step is you
write your template. Then look at it, see what objects you needed
to create on the template, and instantiate them. 
<p>
Since WebMacro is just as happy dealing with a hashtable as a
full fledged Java bean, you can mock up an initial implementation
fairly quickly: populate some hashtables with some mock data and
your template will render it beautifully.
<p>
But this approach is still lacking something: the template author 
has to <i>work through</i> the programmer. Having to go down to 
engineering and wait while the objects are implemented is a 
major pain in the neck--it's an example of one person trying
to work through another.
<p>
True page driven design demands a little better co-operation 
between the template writers and engineering than that.

<h2>Step #2: Provide a library of standard objects</h2>

Page driven organizations do tend to know what kinds of information
their page designers will put on the pages--they just don't know
where it's going to go.
<p>
For example, a page designer creating a page consisting primarily
of $Search results might decide to throw up some $News.Headlines 
in the corner. They might also choose to use a banner $Ad on 
the page as well.
<p>
Ordinarily, the page designer would have to work through engineering,
requesting that these objects be put into the Context so that 
they can be used on each page.
<p>
It would be better if they automatically sprung into existence, 
just because the page designer made use of them.
<p>
WebMacro has a facility to support this, this called ContextTools.

<h2>The ContextTool API</h2>

You can have a set of objects that are automatically instantiated 
in your Context on first use. These objects are called ContextTools.
You write your ContextTool objects and add them to the WebMacro.properties
file. They are then available, automatically, for use on any page. 
<p>
A ContextTool implements this interface:
<pre>
   public interface ContextTool {
      Object init(Context c);
   }
</pre>

The first time the ContextTool is referenced on a template its
init() method will be called. Whatever object is returned by init()
will be placed into the Context exactly as if the servlet programmer
had done a Context.put(ContextTool.init(context)) prior to 
invoking the template.
<p>
Here are the important points about ContextTools:
<ul>
  <li>You don't pay to initialize one unless you use it
  <li>It's only initialized on the *first* use in a template
  <li>Your init method has total control over whether a new
      object is created, or one is returned from some pool
  <li>The template writer cannot detect the difference between
      the programmer having done a Context.put() versus 
      installing the object via a ContextTool
  <li>The init() method can examine the Context for the request
      and potentially perform any kind of back-end query 
      necessary to initialize itself, such as connect to a
      database or query integrator to resolve a search.
</ul>

The net result is that the desired object is automatically created
when and where it is needed, putting the template writer firmly 
in control of what dynamic content appears on which page.
<p>
For example, if a suitable SearchTool were registered in
WebMacro.properties then template writers could write code
like this on every page:
<pre>
   &lt;ul&gt;
   #foreach $result in $Search.Results {
      &lt;li&gt;&lt;a href="$result.URL"&gt;$result.Name&lt;/a&gt;
   }
   &lt;/ul&gt;
</pre>

The $Search object could inspect the form data submitted to the 
page (finding that in the context), and the getResults() method 
would return suitable search results.

<h2>What's right for you?</h2>

Whether you will prefer a page driven development approach, or a 
code driven approach, or something in between is up to you. WebMacro
will support you either way.
<p>
Both approaches preserve the Model/View/Controller separation bewteen
controlling servlet code, the template view, and the back-end model.
The only difference is the mechanism by which the model data gets
into the context: did the controller put it there? Or was it 
loaded on demand by a tool?

</td></tr>
<tr><td><hr></h1></td>
     <td align="right"><a href="script.html">BACK</a> |
                       <a href="index.html">UP</a> |
                       <a href="summary.html">NEXT</a></td></tr>
</table>
</body></html>
